require 'client'
require 'player'
require 'room'

$objects = {}
$objects["bill"] = Player.new :name => "Bill", :location => "player_start", :password => "foozle"
$objects["brendan"] = Player.new :name => "Brendan", :location => "player_start", :password => "barzle"
$objects["phil"] = Player.new :name => "Phil", :location => "player_start", :password => "bazzle"
$objects["mike"] = Player.new :name => "Mike", :location => "player_start", :password => "shempzle"
$objects["player_start"] = Room.new :name => "The First Room"
$objects["player_start"].contents = ["bill", "brendan", "phil", "mike"]

def session_opened(cmd)
  $client.send_text(cmd["sessionId"], "*")
  $client.send_text(cmd["sessionId"], "* Welcome to Heterotopia")
  $client.send_text(cmd["sessionId"], "*")
  $client.send_text(cmd["sessionId"], "* No ID Required For Half-Elves")
  $client.send_text(cmd["sessionId"], "*")
  puts "session_opened session=#{cmd['sessionId']}"
end

def session_closed(cmd)
  $objects.each do |obj|
    if(obj.respond_to?(:sessions))
      obj.sessions.delete(cmd["sessionId"])
    end
  end
  puts "session_closed session=#{cmd['sessionId']}"
  # TODO: find if someone has disconnected
end

def login_player(session, name, password)
  # Find a player
  oname = $objects.keys.find { |obj| $objects[obj].name == name }
  if(oname.nil?)
    return $client.send_text(session, "No such player.")
  end
  candidate = $objects[oname]
  if(candidate.password != password)
    return $client.send_text(session, "Wrong password.")
  end
  candidate.sessions << session
  $client.set_player(session, oname)
  $client.send_text(session, "*** Connected ***")
  $objects[candidate.location].announce "#{candidate.name} has connected"
end

def handle_guest_command(cmd)
  puts "handle_guest_command session=#{cmd['sessionId']}"
  case cmd["command"]
    when /^help/
      $client.send_text(cmd["sessionId"], "No Help For You!")
    when /^connect ([^ ]+) ([^ $]+)/
      login_player(cmd["sessionId"], $1, $2)
    when /^connect ([^$]+)/
      $client.send_text(cmd["sessionId"], "You need to supply a password.")
    else
      $client.send_text(cmd["sessionId"], "I don't understand that.")
  end
end

def handle_player_command(cmd)
  puts "handle_player_command session=#{cmd['sessionId']}"
  player = $objects[cmd["playerObject"]]
  room = $objects[player.location]
  room.announce("#{player.name} typed: #{cmd['command']}")
end

def handle_incoming_command(cmd)
  return session_opened(cmd) if cmd["sessionLifecycle"] == "opened"
  return session_closed(cmd) if cmd["sessionLifecycle"] == "closed"
  return handle_guest_command(cmd) if cmd["playerObject"].nil?
  return handle_player_command(cmd)
end

$client = Heterotopia::Client.new
$client.do_command do |cmd|
  handle_incoming_command(cmd)
end

$client.join
